#include "InterfaceUser.h"

void InterfaceUser::showOpt_v2(const RetornoInfo &RL)
{
    cout<<"\nOla "<<RL.nome<<"\t\t\t\t"<<currentDateTime();
    cout<<"\n1 - Mostrar minhas informacoes\n2 - Mostrar um mural\n3 - Mostar um chat\n4 - Mostrar amigos pendentes\n5 - Mostrar amigos confirmados\n6 - Mostrar uma conta";
    cout<<"\n7 - Adicionar um amigo\n8 - Cadastrar uma mensagem\n9 - Editar minha conta\n10 - Deletar minha conta\n11 - Deslogar";
}

void InterfaceUser::showAcc(const RetornoInfo &RL) const
{
    cout<<"\nSeu nome e : "<<RL.nome;
    cout<<"\nSeu email e : "<<RL.email;
    cout<<"\nSeu aniversario e : "<<RL.niver;
    cout<<"\nSua idade e : "<<RL.idade;
}
void InterfaceUser::showChat(string& srecebido)
{
    bool ok;
    string s;
    Email enviado;
    Email recebido;
    Message mensagem;
    vector<Message> chat;
    recebido.setValor(srecebido);
    do
    {
        ok = true;
        s = Request::getSParameter("Digite o email da conta de quem enviou as mensagens : ");
        try
        {
            enviado.setValor(s);
        }
        catch(invalid_argument &e)
        {
            ok = false;
            notificarErroDigitacao(e);
        }
    }
    while(!ok);
    ComandosNegociosUser comando;
    try
    {
        chat = comando.executarChat(enviado,recebido);
    }
    catch(EErroPersistencia &exp)
    {
        ok = false;
        notificarErroBD(exp);
    }
    if(ok)
    {
        for(unsigned int i = 0; i<chat.size()&&i<10; i++)
        {
            mensagem = chat.at(i);
            showMensagem(mensagem);
        }
    }
}
void InterfaceUser::showMuralPessoa()
{
    bool ok;
    string s;
    Message mensagem;
    Email email;
    vector<Message> mural;
    do
    {
        ok = true;
        s = Request::getSParameter("Digite o email da conta do mural : ");
        try
        {
            email.setValor(s);
        }
        catch(invalid_argument &e)
        {
            ok = false;
            notificarErroDigitacao(e);
        }
    }
    while(!ok);
    ComandosNegociosUser CMDNU;
    try
    {
        mural = CMDNU.executarMural(email);
    }
    catch(EErroPersistencia &exp)
    {
        ok = false;
        notificarErroBD(exp);
    }
    if(ok)
    {
        for(unsigned int i = 0; i<mural.size()&&i<10; i++)
        {
            mensagem = mural.at(i);
            showMensagem(mensagem);
        }
    }
}
void InterfaceUser::showMensagem(Message& mensagem)
{
    cout<<"\n---------------------------------------------------------\n";
    cout<<mensagem.getTempo().getValor()<<"\t\t\t"<<mensagem.getContent();
}
RetornoInfo InterfaceUser::EditarConta(const RetornoInfo &RL)
{
    unsigned int i;
    bool ok;
    RetornoInfo retorno;
    string s;
    Nome nome;
    Senha senha;
    Email email;
    Data data;
    Idade idade;
    Clearance level;
    retorno =  RL;
    do
    {
        ok = true;
        s = Request::getSParameter("O que deseja editar? (1 - nome,2 - senha)");
        if(s == IUser::OptionSenhaS or s == IUser::OptionNomeS or s == IUser::OptionNomeC or s == IUser::OptionSenhaC)
            ok = true;
        else
        {
            ok = false;
            notificarErroDigitacao("Opcao incorreta : ");
        }
    }
    while(!ok);
    if(s == IUser::OptionNomeS or s == IUser::OptionNomeC)
    {
        i = IUser::OptionNomeI;
        do
        {
            ok = true;
            s = Request::getSParameter("Digite seu nome : ");
            retorno.nome = s;
            try
            {
                nome.setValor(retorno.nome);
            }
            catch(invalid_argument &e)
            {
                ok = false;
                notificarErroDigitacao(e);
            }
        }
        while(!ok);
    }
    else if(s == IUser::OptionSenhaS or s == IUser::OptionSenhaC)
    {
        i = IUser::OptionSenhaI;
        do
        {
            ok = true;
            s = Request::getSParameter("Digite sua senha (minimo de 4 caracteres) : ");
            retorno.senha = s;
            try
            {
                senha.setValor(retorno.senha);
            }
            catch(invalid_argument &e)
            {
                ok = false;
                notificarErroDigitacao(e);
            }
        }
        while(!ok);
    }
    if(i==IUser::OptionNomeI)
    {
        senha.setValor(retorno.senha);
    }
    else
    {
        nome.setValor(retorno.nome);
    }
    email.setValor(retorno.email);
    data.setValor(retorno.niver);
    idade.setValor(retorno.idade);
    level.setValor(retorno.clearance);
    ComandosNegociosUser comando;
    try
    {
        comando.executarUpdate(nome,idade,data,email,senha,level);
    }
    catch(EErroPersistencia &exp)
    {
        ok = false;
        notificarErroBD(exp);
        retorno = RL;
    }
    if(ok)
    {
        notificarSucessoOperacao();
    }
    return retorno;
}

bool InterfaceUser::DeletarConta(RetornoInfo& RL)
{
    bool ok=true;
    Email email;
    email.setValor(RL.email);
    ComandosNegociosUser comando;
    try
    {
        comando.executarRemocao(email);
    }
    catch(EErroPersistencia &exp)
    {
        notificarErroBD(exp);
        ok = false;
    }
    if(ok)
    {
        notificarSucessoOperacao();
    }
    return ok;
}
void InterfaceUser::CadastrarAmigo(const RetornoInfo& RL)
{
    Amigo frnd;
    Email enviado(RL.email);
    Email recebido;
    int estado = Estados::PENDENTE;
    string s;
    bool ok;
    do
    {
        ok = true;
        s = Request::getSParameter("Digite o email da conta que deseja adicionar como amigo : ");
        try
        {
            recebido.setValor(s);
        }
        catch(invalid_argument &e)
        {
            ok = false;
            notificarErroDigitacao(e);
        }
    }
    while(!ok);
    frnd.setBasicInfo(enviado,recebido,estado);
    ComandosNegociosUser comando;
    try
    {
        comando.executarCadastroAmigo(frnd);
    }
    catch(EErroPersistencia &e)
    {
        ok = false;
        notificarErroBD(e);
    }
    if(ok)
    {
        notificarSucessoOperacao();
    }
}
void InterfaceUser::CadastrarMensagem(string& senviado)
{
    string s;
    bool ok;
    string srecebido;
    Email recebido;
    Email enviado(senviado);
    TempoSistema ts(currentDateTime());
    Message mensagem;
    s = Request::getSParameter("Deseja enviar uma mensagem para seu mural ou para alguem? (1 - alguem, 2 - mural) : ");
    if(s == IUser::OptionAlguemS or s == IUser::OptionAlguemC)
    {
        do
        {
            ok = true;
            s = Request::getSParameter("Digite o email de quem deseja enviar a mensagem : ");
            try
            {
                recebido.setValor(s);
                srecebido = s;
            }
            catch(invalid_argument &e)
            {
                ok = false;
                notificarErroDigitacao(e);
            }
        }
        while(!ok);
    }
    else if(s == IUser::OptionMuralS or s == IUser::OptionMuralC)
    {
        srecebido = IUser::OptionMuralS;
    }
    s = Request::getSParameter("Digite sua mensagem : ");
    mensagem.setBasicInfo(enviado,s,ts,srecebido);
    ComandosNegociosUser comando;
    try
    {
        ok = true;
        comando.executarCadastroMensagem(mensagem);
    }
    catch(EErroPersistencia &exp)
    {
        ok = false;
        notificarErroBD(exp);
    }
    if(ok)
        notificarSucessoOperacao();
}
void InterfaceUser::showPendentes(string& meu_email)
{
    bool ok;
    string s;
    Email enviado;
    Email recebido(meu_email);
    vector<string> pendentes;
    int estado = Estados::PENDENTE;
    ComandosNegociosUser comando;
    try
    {
        pendentes = comando.executarPendentes(recebido,estado);
    }
    catch(EErroPersistencia &exp)
    {
        notificarErroBD(exp);
        return;
    }
    cout<<"---------------------PENDENTES----------------------------------\n";
    for(unsigned int i=0; i<pendentes.size(); i++)
    {
        cout<<pendentes.at(i)<<"\n";
    }
    cout<<"----------------------------------------------------------------\n";
    do
    {
        ok = true;
        s = Request::getSParameter("Digite o email do amigo que deseja aceitar ou recusar : ");
        try
        {
            enviado.setValor(s);
        }
        catch(invalid_argument &e)
        {
            ok = false;
            notificarErroDigitacao(e);
        }
    }
    while(!ok);
    do
    {
        ok = true;
        s = Request::getSParameter("1 - Aceitar, 2 - Recusar : ");
        if(s != IUser::AceitarNUM and s!= IUser::RecusarNUM)
        {
            ok = false;
            notificarErroDigitacao("Opcao invalida, digite novamente : ");
        }
    }while(!ok);
    if(s == IUser::AceitarNUM)
    {
        try
        {
            comando.executarUpdate(enviado,recebido,s);
        }
        catch(EErroPersistencia &exp)
        {
            ok = false;
            notificarErroBD(exp);
        }
    }
    else
    {
        try
        {
            comando.executarUpdate(enviado,recebido,s);
        }
        catch(EErroPersistencia &exp)
        {
            ok = false;
            notificarErroBD(exp);
        }
    }
    if(ok)
        notificarSucessoOperacao();
}
void InterfaceUser::showConfirmados(string& meu_email)
{
    Email meu_enviado(meu_email);
    Email meu_recebido(meu_email);
    vector<string> confirmados1;
    vector<string> confirmados2;
    int estado = Estados::CONFIRMADO;
    ComandosNegociosUser comando;
    try
    {
        confirmados1 = comando.executarConfirmados_v1(meu_enviado,estado);
    }
    catch(EErroPersistencia &exp)
    {
       //Nada a fazer;
    }try
    {
        confirmados2 = comando.executarConfirmados_v2(meu_recebido,estado);
    }
    catch(EErroPersistencia &exp)
    {
       //Nada a fazer;
    }
    size_t dst_size = confirmados2.size();
    size_t src_size = confirmados1.size();
    // Aumenta o tamanho do vetor
    confirmados1.reserve(src_size + dst_size);
    // Junta of vetores
    confirmados1.insert(confirmados1.begin() + src_size, confirmados2.begin(), confirmados2.end());
    // Ajeita em ordem alfabetica
    std::sort(confirmados1.begin(), confirmados1.end());
    cout<<"---------------------AMIGOS-------------------------------------\n";
    for(unsigned int i=0; i<confirmados1.size(); i++)
    {
        cout<<confirmados1.at(i)<<"\n";
    }
    cout<<"----------------------------------------------------------------\n";
}
void InterfaceUser::showContaPessoa(const Email& email)
{
    RetornoInfo retorno;
    ComandosNegociosUser comando;
    try
    {
        retorno = comando.executarMostraConta(email);
    }
    catch(EErroPersistencia &exp)
    {
        notificarErroBD(exp);
    }
    cout<<"\nO nome e : "<<retorno.nome;
    cout<<"\nO email e : "<<retorno.email;
    cout<<"\nO aniversario e : "<<retorno.niver;
    cout<<"\nA idade e : "<<retorno.idade;
}
void InterfaceUser::executar_v2(RetornoInfo &RL)
{
    string s;
    bool ok;
    do
    {
        showOpt_v2(RL);
        s = Request::getSParameter("\nO que deseja fazer?");
        if(s == IUser::ShowAccNUM)
        {
            showAcc(RL);
        }
        else if(s == IUser::ShowMuralNUM)
        {
            showMuralPessoa();
        }
        else if(s == IUser::ShowChatNUM)
        {
            showChat(RL.email);
        }
        else if(s == IUser::ShowPendentesNUM)
        {
            showPendentes(RL.email);
        }
        else if(s == IUser::ShowConfirmadosNUM)
        {
            showConfirmados(RL.email);
        }
        else if(s == IUser::ShowAccElseNUM)
        {
            bool ok;
            s = Request::getSParameter("\nDigite o email da conta a ser mostrada : ");
            Email email;
            do
            {
                ok = true;
                try
                {
                    email.setValor(s);
                }
                catch(invalid_argument &e)
                {
                    notificarErroDigitacao(e);
                }
            }
            while(!ok);
            showContaPessoa(email);
        }
        else if(s == IUser::CadastrarAmigoNUM)
        {
            CadastrarAmigo(RL);
        }
        else if(s == IUser::CadastrarMensagemNUM)
        {
            CadastrarMensagem(RL.email);
        }
        else if(s == IUser::EditarContaNUM)
        {
            RL = EditarConta(RL);
        }
        else if(s == IUser::DeletarContaNUM)
        {
            ok = DeletarConta(RL);
            if(ok)
            {
                s = IUser::DeslogarNUM;
            }
        }
    }
    while(s!=IUser::DeslogarNUM);
}
